﻿using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Runtime.Serialization;
using System.Xml.Serialization;

namespace WeiboPlus.Models
{
    [Table(Name = "sns_account")]
    public class SNSAccount : NotificationObject, IEquatable<SNSAccount>
    {
        public SNSAccount()
        {
            _serviceProvider = SNSProviderType.Unknow;
        }

        public SNSAccount(SNSProviderType svcProvider, int accountNum)
        {
            _serviceProvider = svcProvider;
            _accountID = accountNum;
            AccountStatus = SNSAccountStatus.UnAuthorized;
        }

        bool _isDestination = true;
        [Column(Name = "is_destination")]
        public bool IsDestination
        {
            get
            {
                return _isDestination;
            }
            set
            {
                RaisePropertyChanging("IsDestination");
                _isDestination = value;
                RaisePropertyChanged("IsDestination");
            }
        }

        int _accountID;
        [Column(Name = "account_id", IsPrimaryKey = true)]
        public int AccountID
        {
            get
            {
                return _accountID;
            }
            set
            {
                RaisePropertyChanging("AccountID");
                _accountID = value;
                RaisePropertyChanged("AccountID");
            }
        }

        SNSProviderType _serviceProvider;
        [Column(Name = "sp_type")]
        public SNSProviderType ServiceProvider
        {
            get
            {
                return _serviceProvider;
            }
            set
            {
                RaisePropertyChanging("ServiceProvider");
                _serviceProvider = value;
                RaisePropertyChanged("ServiceProvider");
            }
        }

        [XmlIgnore]
        [IgnoreDataMember]
        public bool IsAuthorized
        {
            get { return (SNSAccountStatus.Authorized & AccountStatus) == SNSAccountStatus.Authorized; }
        }

        bool _isBind;
        [Column(Name = "is_bind")]
        public bool IsBind
        {
            get
            {
                return _isBind;
            }
            set
            {
                RaisePropertyChanging("IsBind");
                _isBind = value;
                RaisePropertyChanged("IsBind");
            }
        }

        SNSAccountStatus _accountStatus;
        [Column(Name = "account_status")]
        public SNSAccountStatus AccountStatus
        {
            get
            {
                return _accountStatus;
            }
            set
            {
                RaisePropertyChanging("AccountStatus");
                _accountStatus = value;
                RaisePropertyChanged("AccountStatus");
            }
        }

        string _authorizeURL;
        [Column(Name = "authorize_url")]
        public string AuthorizeURL
        {
            get
            {
                return _authorizeURL;
            }
            set
            {
                RaisePropertyChanging("AuthorizeURL");
                _authorizeURL = value;
                RaisePropertyChanged("AuthorizeURL");
            }
        }

        string _pin;
        public string PIN
        {
            get
            {
                return _pin;
            }
            set
            {
                RaisePropertyChanging("PIN");
                _pin = value;
                RaisePropertyChanged("PIN");
            }
        }

        string _oauthToken;
        [Column(Name = "oauth_token")]
        public string OAuthToken
        {
            get
            {
                return _oauthToken;
            }
            set
            {
                RaisePropertyChanging("OAuthToken");
                _oauthToken = value;
                RaisePropertyChanged("OAuthToken");
            }
        }

        string _oauthTokenSecret;
        [Column(Name = "oauth_token_secret")]
        public string OAuthTokenSecret
        {
            get
            {
                return _oauthTokenSecret;
            }
            set
            {
                RaisePropertyChanging("OAuthTokenSecret");
                _oauthTokenSecret = value;
                RaisePropertyChanged("OAuthTokenSecret");
            }
        }

        string _accessToken;
        [Column(Name = "access_token")]
        public string AccessToken
        {
            get
            {
                return _accessToken;
            }
            set
            {
                RaisePropertyChanging("AccessToken");
                _accessToken = value;
                RaisePropertyChanged("AccessToken");
            }
        }

        string _accessTokenSecret;
        [Column(Name = "access_token_secret")]
        public string AccessTokenSecret
        {
            get
            {
                return _accessTokenSecret;
            }
            set
            {
                RaisePropertyChanging("AccessTokenSecret");
                _accessTokenSecret = value;
                RaisePropertyChanged("AccessTokenSecret");
            }
        }

        string _displayName;
        [Column(Name = "display_name")]
        public string DisplayName
        {
            get
            {
                return _displayName;
            }
            set
            {
                RaisePropertyChanging("DisplayName");
                _displayName = value;
                RaisePropertyChanged("DisplayName");
            }
        }

        string _avtarUri;
        [Column(Name = "avtar_uri")]
        public string AvtarUri
        {
            get
            {
                return _avtarUri;
            }
            set
            {
                RaisePropertyChanging("AvtarUri");
                _avtarUri = value;
                RaisePropertyChanged("AvtarUri");
            }
        }

        string _userName;
        [Column(Name = "user_name")]
        public string UserName
        {
            get
            {
                return _userName;
            }
            set
            {
                RaisePropertyChanging("UserName");
                _userName = value;
                RaisePropertyChanged("UserName");
            }
        }

        string _password;
        [Column(Name = "password")]
        public string Password
        {
            get
            {
                return _password;
            }
            set
            {
                RaisePropertyChanging("Password");
                _password = value;
                RaisePropertyChanged("Password");
            }
        }

        string _refreshToken;
        [Column(Name = "refresh_token")]
        public string RefreshToken
        {
            get
            {
                return _refreshToken;
            }
            set
            {
                RaisePropertyChanging("RefreshToken");
                _refreshToken = value;
                RaisePropertyChanged("RefreshToken");
            }
        }

        int _expiresIn;
        [Column(Name = "expires_in")]
        public int ExpiresIn
        {
            get
            {
                return _expiresIn;
            }
            set
            {
                RaisePropertyChanging("ExpiresIn");
                _expiresIn = value;
                RaisePropertyChanged("ExpiresIn");
            }
        }

        string _scope;
        [Column(Name = "scope")]
        public string Scope
        {
            get
            {
                return _scope;
            }
            set
            {
                RaisePropertyChanging("Scope");
                _scope = value;
                RaisePropertyChanged("Scope");
            }
        }

        //private BitmapImage faceImage;

        //public BitmapImage FaceImage
        //{
        //    get { return faceImage; }
        //    set { faceImage = value; }
        //}

        [Column(Name = "user_account_id")]
        int _userAccountID;
        [Column(Name = "user_sp_type")]
        SNSProviderType _userServiceProvider;

        EntityRef<SNSUser> _userLite;
        [Association(Name = "fk_account_user", ThisKey = "_userAccountID,_userServiceProvider", OtherKey = "AccountID,ServiceProvider")]
        public SNSUser UserLite
        {
            get
            {
                return _userLite.Entity;
            }
            set
            {
                RaisePropertyChanging("UserLite");
                _userLite.Entity = value;
                if (value != null)
                {
                    _userAccountID = value.AccountID;
                    _userServiceProvider = value.ServiceProvider;
                }
                RaisePropertyChanged("UserLite");
            }
        }

        bool _isActive = true;
        [Column(Name = "is_active")]
        public bool IsActive
        {
            get
            {
                return _isActive;
            }
            set
            {
                RaisePropertyChanging("IsActive");
                _isActive = value;
                RaisePropertyChanged("IsActive");
            }
        }

        bool _isDelete;
        [Column(Name = "is_delete")]
        public bool IsDelete
        {
            get
            {
                return _isDelete;
            }
            set
            {
                RaisePropertyChanging("IsDelete");
                _isDelete = value;
                RaisePropertyChanged("IsDelete");
            }
        }

        bool _isDuplicate;
        [Column(Name = "is_duplicate")]
        public bool IsDuplicate
        {
            get
            {
                return _isDuplicate;
            }
            set
            {
                RaisePropertyChanging("IsDuplicate");
                _isDuplicate = value;
                RaisePropertyChanged("IsDuplicate");
            }
        }

        [Column(IsVersion = true)]
#pragma warning disable 0168, 0169
        private Binary _version;
#pragma warning restore 0168, 0169

        public override string ToString()
        {
            var s = string.Format(
                "{0}({1}, {2})",
                AccountID,
                ServiceProvider,
                UserLite != null ? UserLite.AccountName : null
                );

            return s;
        }

        #region IEquatable<SNSAccount> Members

        public bool Equals(SNSAccount other)
        {
            var rv = false;

            if (other != null)
            {
                rv = this.AccountID == other.AccountID
                    && this.ServiceProvider == other.ServiceProvider
                    && this.UserName == other.UserName;
            }

            return rv;
        }

        #endregion
    }

    public class SNSAccountComparer : IEqualityComparer<SNSAccount>
    {
        #region IEqualityComparer<SNSAccount> Members

        public bool Equals(SNSAccount x, SNSAccount y)
        {
            if (x != null && y != null)
            {
                return x.Equals(y);
            }
            else
            {
                return false;
            }
        }

        public int GetHashCode(SNSAccount obj)
        {
            var s = obj.ToString();
            var v = s.GetHashCode();

            return v;
        }

        #endregion
    }
}
